package com.qiyun.asyncarrange;
//197
import java.util.concurrent.*;


public class CompletableFutureTest02 {
    public static ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
            200,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(100000),
            Executors.defaultThreadFactory(),//默认线程工厂
            new ThreadPoolExecutor.AbortPolicy()//拒绝策略
            //如果不想抛弃还要执行。可以使用new ThreadPoolExecutor.CallerRunsPolicy()
    );


    public static void main(String[] args) throws ExecutionException, InterruptedException {

        /**
         * 计算完成时回调方法
         * public CompletableFuture<T> whenComplete (BiConsumer<? super T, ? super Throwable> action)
         * public CompletableFuture<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action)
         * public CompletableFuture<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action, Executor executor)
         * public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)
         *
         *
         * whenComplete 可以处理正常和异常的计算结果，exceptionally 处理异常情况。
         *
         * whenComplete 和 whenCompleteAsync 的区别：
         *
         * whenComplete：是执行当前任务的线程执行继续执行 whenComplete 的任务。
         * whenCompleteAsync：是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。
         *
         *
         * whenComplete 虽然能得到异常信息，但是无法修改返回数据。
         * exceptionally 可以感知异常，同时返回默认值
         *
         */

        System.out.println("main--start---");

        // 无返回值的
       /* CompletableFuture.runAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果...");
        }, executor);*/

        // 有返回值的
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果..." + i);
            return i;

        }, executor).whenCompleteAsync((res, exception) -> {

            //whenComplete 虽然能得到异常信息，但是没发修改返回数据
            System.out.println("异步任务成功完成了......结果是" + res);
            System.out.println("异步任务成功完成了......异常是" + exception);

        }).exceptionally(throwable -> {
            //exceptionally 可以感知异常，同时线程出现异常，给出处理办法
            //如果出现异常我们就返回默认值10
            return 10;
        });
        System.out.println("异步执行的结果为" + future.get());
        System.out.println("main--end---");

    }

}
